#if 0
#pragma once
#include <iostream>
#include <pthread.h>
#include <queue>
#include <vector>
#include "Log.hpp"
#include "Cond.hpp"
#include "Mutex.hpp"
#include "Thread.hpp"
using namespace std;
using namespace my_log;
using namespace my_cond;
using namespace my_mutex;
using namespace my_thread;
#define NUM 5
namespace my_threadpool
{
    template <typename T>
    class ThreadPool
    {
    private:
        ThreadPool(const ThreadPool<T> &) = delete;
        ThreadPool<T> &operator=(const ThreadPool<T> &) = delete;
        void WakeAllThread()
        {
            LockGuard lock(_lock);
            _cond.Broadcast();
        }
        void WakeOnceThread()
        {
            _cond.Signal();
        }
        ThreadPool(int num = NUM)
            : _sleepnum(0), _isrunning(false)
        {
            for (int i = 0; i < num; i++)
            {
                _threads.emplace_back(
                    [this]()
                    {
                        HandlerTask();
                    });
            }
        }
        void HandlerTask()
        {
            _isrunning = true;
            while (true)
            {
                T tk;
                LockGuard lock(_lock);
                {
                    while (_taskq.empty() && _isrunning)
                    {
                        _sleepnum++;
                        _cond.Wait(_lock);
                        _sleepnum--;
                    }
                    if (!_taskq.empty())
                    {
                        tk = _taskq.front();
                        _taskq.pop();
                    }
                    else
                        break;
                }
                tk(); // 类仿函数更优雅
            }
        }
        void Stop()
        {
            if (!_isrunning)
                return;
            _isrunning = false;
            // 唤醒所有线程
            WakeAllThread();
            LOG(Level::INFO) << "所有线程被唤醒";
        }
        ~ThreadPool()
        {
        }

    public:
        static ThreadPool<T> *GetTreadPool()
        {
            if (_pthreadpool == nullptr)
            {
                LockGuard lock(_lock2);
                if (_pthreadpool == nullptr)
                {
                    LOG(Level::INFO) << "ThreadPool创建";
                    _pthreadpool = new ThreadPool<T>();
                }
            }
            return _pthreadpool;
        }
        bool Push(const T &task)
        {
            if (_isrunning)
            {
                LockGuard lock(_lock);
                {
                    _taskq.push(task);
                    if (_sleepnum == _threads.size())
                        WakeOnceThread();// 唤醒一个线程
                }
                return true;
            }
            return false;
        }
        void Join()
        {
            Stop();
            for (auto &thread : _threads)
            {
                LOG(Level::INFO) << "线程" << thread.getname() << "等待成功";
                thread.Join();
            }
        }

    private:
        vector<thread<T>> _threads;
        queue<T> _taskq;
        Mutex _lock;
        Cond _cond;
        int _sleepnum;
        bool _isrunning;
        static ThreadPool<T> *_pthreadpool;
        static Mutex _lock2;
    };

    template <typename T>
    ThreadPool<T> *ThreadPool<T>::_pthreadpool = nullptr;

    template <typename T>
    Mutex ThreadPool<T>::_lock2;
}
#endif
#pragma once
#include <iostream>
#include <pthread.h>
#include <queue>
#include <vector>
#include "Cond.hpp"
#include "Mutex.hpp"
#include "Thread.hpp"
using namespace std;
using namespace my_cond;
using namespace my_mutex;
using namespace my_thread;
#define NUM 5
namespace my_threadpool
{
    template <typename T>
    class ThreadPool
    {
    private:
        ThreadPool(const ThreadPool<T> &) = delete;
        ThreadPool<T> &operator=(const ThreadPool<T> &) = delete;
        ThreadPool(int num = NUM)
            : _sleepnum(0), _isrunning(false)
        {
            for (int i = 0; i < num; i++)
            {
                _threads.emplace_back(
                    [this]()
                    {
                        HandlerTask();
                    });
            }
        }
        void WakeAllThread()
        {
            LockGuard lock(_lock);
            _cond.Broadcast();
        }
        void WakeOnceThread()
        {
            _cond.Signal();
        }
        void HandlerTask()
        {
            _isrunning = true;
            while (true)
            {
                T tk;
                LockGuard lock(_lock);
                {
                    while (_taskq.empty() && _isrunning)
                    {
                        _sleepnum++;
                        _cond.Wait(_lock);
                        _sleepnum--;
                    }
                    if (!_taskq.empty())
                    {
                        tk = _taskq.front();
                        _taskq.pop();
                    }
                    else
                        break;
                }
                tk();
            }
        }
        void Stop()
        {
            _isrunning = false;
            WakeAllThread();
            cout << "所有线程被唤醒" << endl;
        }
        ~ThreadPool()
        {
        }

    public:
        static ThreadPool<T> *GetTreadPool()
        {
            if (_pthreadpool == nullptr)
            {
                LockGuard lock(_lock2);
                if (_pthreadpool == nullptr)
                {
                    cout << "ThreadPool创建" << endl;
                    _pthreadpool = new ThreadPool<T>();
                }
            }
            return _pthreadpool;
        }
        bool Push(const T &task)
        {
            if (_isrunning)
            {
                LockGuard lock(_lock);
                {
                    _taskq.push(task);
                    if (_sleepnum == _threads.size())
                        WakeOnceThread(); // 唤醒一个线程
                }
                return true;
            }
            return false;
        }
        void Join()
        {
            if (!_isrunning)
                return;
            Stop();
            for (auto &thread : _threads)
            {
                thread.Join();
                cout << "线程" << thread.getname() << "等待成功" << endl;
            }
        }

    private:
        vector<thread> _threads;
        queue<T> _taskq;
        Mutex _lock;
        Cond _cond;
        int _sleepnum;
        bool _isrunning;
        static ThreadPool<T> *_pthreadpool;
        static Mutex _lock2;
    };
    template <typename T>
    ThreadPool<T> *ThreadPool<T>::_pthreadpool = nullptr;
    template <typename T>
    Mutex ThreadPool<T>::_lock2;
}
